<template>
  <div id="app">
    <!--视窗-->
    <div class="viewport" :style="viewportStyle">
      <div style="position: absolute; width: 100%; height: 100%; top: 0px; left: 0px;">
        <div :style="pageStyle" class="page">
          <template v-for="(element,i) in page.elements">
            <div :key="i + 'a'" :style="elementStyle2(element)" v-if="element.angle!==0"></div>
            <div :key="i" :style="elementStyle(element)"></div>
          </template>
          
        </div>
      </div>
      <!-- <svg
        :width="viewport.width"
        :height="viewport.height"
        :viewBox.camel="viewBox"
        xmlns="http://www.w3.org/2000/svg"
        style="position: absolute; top: 0px; left: 0px;">
      </svg> -->
      <svg
        :viewBox.camel="viewBoxString"
        xmlns="http://www.w3.org/2000/svg"
        style="position: absolute; width: 100%; height: 100%; top: 0px; left: 0px;" @click="selectElement(null)">
        <!-- <g stroke="green" fill="white" stroke-width="5">
          <circle cx="25" cy="25" r="15" />
          <circle cx="40" cy="25" r="15" />
          <circle cx="55" cy="25" r="15" />
          <circle cx="70" cy="25" r="15" />
        </g> -->
        <g>
          <rect id="zoomPanel" :x="viewBox.x" :y="viewBox.y" :width="viewBox.width" :height="viewBox.height"/>
        </g>
        <g :transform="globalTransform">
          <rect v-for="(element,i) in page.elements" :key="i" :x="element.x" :y="element.y" :width="element.width" :height="element.height" @click.stop="selectElement(element)" class="element-panel"/>
          <g :transform="dragPanelTransform">
            <rect id="dragPanel" :x="dragPanel.x" :y="dragPanel.y" :width="dragPanel.width" :height="dragPanel.height"/>
            <rect id="dragPointN" cursor="ns-resize" :x="dragPointN.x" :y="dragPointN.y" :width="dragPointSize" :height="dragPointSize" class="drag-point"></rect><!-- ↑ -->
            <rect id="dragPointE" cursor="ew-resize" :x="dragPointE.x" :y="dragPointE.y" :width="dragPointSize" :height="dragPointSize" class="drag-point"></rect><!-- → -->
            <rect id="dragPointS" cursor="ns-resize" :x="dragPointS.x" :y="dragPointS.y" :width="dragPointSize" :height="dragPointSize" class="drag-point"></rect><!-- ↓ -->
            <rect id="dragPointW" cursor="ew-resize" :x="dragPointW.x" :y="dragPointW.y" :width="dragPointSize" :height="dragPointSize" class="drag-point"></rect><!-- ← -->
            <!-- ↖ -->
            <!-- <rect id="dragPointNW" cursor="nwse-resize" :x="dragPointNW.x" :y="dragPointNW.y" :width="dragPointSize" :height="dragPointSize" class="drag-point"></rect> -->
            <!-- ↗ -->
            <!-- <rect id="dragPointNE" cursor="nesw-resize" :x="dragPointNE.x" :y="dragPointNE.y" :width="dragPointSize" :height="dragPointSize" class="drag-point"></rect> -->
            <!-- ↘ -->
            <!-- <rect id="dragPointSE" cursor="nwse-resize" :x="dragPointSE.x" :y="dragPointSE.y" :width="dragPointSize" :height="dragPointSize" class="drag-point"></rect> -->
            <!-- ↙ -->
            <!-- <rect id="dragPointSW" cursor="nesw-resize" :x="dragPointSW.x" :y="dragPointSW.y" :width="dragPointSize" :height="dragPointSize" class="drag-point"></rect> -->
          </g>
        </g>
      </svg>
    </div>
  </div>
</template>

<script>
import page from './page.js'
import { scaleRect1IntoRect2, scaleRect1OutRect2 } from './utils'
import * as d3 from 'd3'

export default {
  name: 'App',
  data: function () {
    return {
      page: page,
      viewport: {
        width: 1200,
        height: 1200
      },
      elementSelected: null
    }
  },
  computed: {
    viewportStyle: function () {
      return {
        width: this.viewport.width + 'px',
        height: this.viewport.height + 'px'
      }
    },
    pageStyle: function () {
      const rect = scaleRect1IntoRect2(this.page.width, this.page.height, this.viewport.width, this.viewport.height)
      console.log(rect)
      const c1x = rect.width / 2 + rect.x
      const c1y = rect.height / 2 + rect.y
      const c2x = this.page.width / 2
      const c2y = this.page.height / 2
      console.log(c1x, c1y, c2x, c2y)
      const scale = rect.width / this.page.width
      return {
        width: this.page.width + 'px',
        height: this.page.height + 'px',
        transform: `translate(${c1x - c2x}px, ${c1y - c2y}px) scale(${scale})`
      }
    },
    viewBox: function () {
      const rect = scaleRect1OutRect2(this.viewport.width, this.viewport.height, this.page.width, this.page.height)
      return {
        x: 0,
        y: 0,
        width: rect.width,
        height: rect.height
      }
    },
    scaleValue: function () {
      return this.viewBox.width / this.viewport.width
    },
    viewBoxString: function () {
      return `0 0 ${this.viewBox.width} ${this.viewBox.height}`
    },
    globalTransform: function () {
      const rect = scaleRect1OutRect2(this.viewport.width, this.viewport.height, this.page.width, this.page.height)
      return `translate(${rect.x * -1} ${rect.y * -1})`
    },
    dragPanel: function () {
      let position = {
        x: 0,
        y: 0,
        width: 0,
        height: 0
      }
      if (this.elementSelected) {
        position.x = this.elementSelected.x
        position.y = this.elementSelected.y
        position.width = this.elementSelected.width
        position.height = this.elementSelected.height
      }
      return position
    },
    dragPointSize: function () {
      const value = 10 * this.scaleValue
      return this.elementSelected ? value : 0
    },
    dragPointSizeHalf: function () {
      return this.dragPointSize / 2
    },
    dragPointN: function () {
      return {
        x: this.dragPanel.x + this.dragPanel.width / 2 - this.dragPointSizeHalf,
        y: this.dragPanel.y - this.dragPointSizeHalf
      }
    },
    dragPointE: function () {
      return {
        x: this.dragPanel.x + this.dragPanel.width - this.dragPointSizeHalf,
        y: this.dragPanel.y + this.dragPanel.height / 2 - this.dragPointSizeHalf
      }
    },
    dragPointS: function () {
      return {
        x: this.dragPanel.x + this.dragPanel.width / 2 - this.dragPointSizeHalf,
        y: this.dragPanel.y + this.dragPanel.height - this.dragPointSizeHalf
      }
    },
    dragPointW: function () {
      return {
        x: this.dragPanel.x - this.dragPointSizeHalf,
        y: this.dragPanel.y + this.dragPanel.height / 2 - this.dragPointSizeHalf
      }
    },
    dragPanelTransform: function () {
      if (this.elementSelected) {
        return `rotate(${this.elementSelected.angle}, ${this.dragPanel.x + this.dragPanel.width / 2} ${this.dragPanel.y + this.dragPanel.height / 2})`
      }
      return ''
    }
  },
  created () {
    console.log(page)
  },
  mounted () {
    console.log('scaleValue:' + this.scaleValue)
    // let dx = 0
    // let dy = 0
    d3.select('#dragPanel')
      .call(d3.drag()
        .container(function () {
          // default
          return this.parentNode
        })
        .on('start', (event) => {
          console.log(event)
          // dx = event.sourceEvent.layerX
          // dy = event.sourceEvent.layerY
        })
        .on('drag', (event) => {
          this.elementSelected.x += event.dx
          this.elementSelected.y += event.dy
        })
        .on('end', (event) => {
          console.log(event)
        })
      )
    
    d3.select('#dragPointN')
      .call(d3.drag()
        .container(function () {
          return this.parentNode
        })
        .on('start', (event) => {
          console.log(event)
        })
        .on('drag', (event) => {
          this.elementSelected.y += event.dy
          this.elementSelected.height -= event.dy
        })
        .on('end', (event) => {
          console.log(event)
        })
      )
    
    d3.select('#dragPointS')
      .call(d3.drag()
        .container(function () {
          return this.parentNode
        })
        .on('start', (event) => {
          console.log(event)
        })
        .on('drag', (event) => {
          this.elementSelected.height += event.dy
        })
        .on('end', (event) => {
          console.log(event)
        })
      )
    
    d3.select('#dragPointE')
      .call(d3.drag()
        .container(function () {
          return this.parentNode
        })
        .on('start', (event) => {
          console.log(event)
        })
        .on('drag', (event) => {
          this.elementSelected.width += event.dx
        })
        .on('end', (event) => {
          console.log(event)
        })
      )
    
    d3.select('#dragPointW')
      .call(d3.drag()
        .container(function () {
          return this.parentNode
        })
        .on('start', (event) => {
          console.log(event)
        })
        .on('drag', (event) => {
          this.elementSelected.x += event.dx
          this.elementSelected.width -= event.dx
        })
        .on('end', (event) => {
          console.log(event)
        })
      )
  },
  methods: {
    test: function () {},
    elementStyle: function (element) {
      let obj = {
        position: 'absolute',
        top: element.y + 'px',
        left: element.x + 'px',
        width: element.width + 'px',
        height: element.height + 'px',
        'background-color': element.shape.color
      }
      if (element.angle > 0) {
        obj.transform = 'rotate(45deg)'
      }
      return obj
    },
    elementStyle2: function (element) {
      let obj = this.elementStyle(element)
      obj.opacity = 0.5
      obj.transform = ''
      return obj
    },
    selectElement: function (element) {
      this.elementSelected = element
      console.log(this.elementSelected)
    }
  }
}
</script>

<style>
/* #app {} */
.viewport {
  border: solid 1px;
  position: relative;
  margin: 50px auto 0;
  box-sizing: content-box;
}
.canvas { background-color: lightgray; position: relative; }
.page { background-color: lightblue; position: relative; overflow: hidden; }
.pointer { cursor: pointer; }
.element-panel {
  cursor: pointer;
  fill-opacity: 0;
}
#dragPanel {
  stroke: #38f;
  stroke-width: 1;
  /* stroke-dasharray: 6 4; */
  fill-opacity: 0;
  cursor: move;
}
.drag-point {
  stroke: #38f;
  stroke-width: 1;
  fill: white;
}
#zoomPanel {
  fill-opacity: 0;
}
</style>
